﻿#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QString>
#include <QTime>
#include <QDateTime>
#include <QDebug>
#include <QMessageBox>
#include <QCheckBox>
#include <QVariant>
#include <QPlainTextEdit>
#include <QFileDialog>
#include <QtCharts>
#include <QRandomGenerator>
#include <QDir>

#include <array>

#include "serial_dev.h"
#include "ChartView.h"
#include "protocol.h"
#include "serialport.h"
#include "tracker1D_api.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

QT_CHARTS_USE_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    struct track1d
    {
        we_u32 id;
        float  range;
    };

    struct RangeConfiguartion {
        int32_t search_index;
        std::array<uint16_t, 8> index;
        std::array<float, 8> gain;
        std::array<float, 8> czt;
        std::vector<track1d> result;
        void clear() {
            search_index = -1;
            index.fill(0);
            gain.fill(0.0f);
            czt.fill(0.0f);
            result.clear();
        }
    };

    struct SpeedProfile {
        float range;
        float velocity;
        float snr;
        float res;
        SpeedProfile() = default;
    };

    struct SpeedConfiguration {
        std::vector<SpeedProfile> profiles;
        void clear() {
            profiles.clear();
        }
    };

private:
    // 事件总线
    std::shared_ptr<EventBus> serialbus;
    // 协议管理器
    std::shared_ptr<ProtocolManager> ProtocolManager_;
    // 协议处理器
    std::shared_ptr<ProtocolHandler> ProtocolHandler_;
    // 串口对象
    std::shared_ptr<SerialPort> SerialPort_;

    void setupUIControls();
    void setupChartVisualization();
    void setupLogFolders();
    void setupSerialPortUI();
    QStringList scanAvailableSerialPorts();

    QChart chart;
    QLineSeries FFTSeries;              //频谱数据
    QLineSeries ThresholdSeries;        //阈值数据
    QGraphicsTextItem ResultText;       //标记数据
    QTimer QChartRefreshTimer;

    static constexpr int MaskLength = 5;
    static constexpr int MAX_OBJECTS = 8;

    void processDeviceData(std::vector<uint16_t>& data);
    void processLevelData(std::vector<uint16_t>& data);
    void processLiquidData(std::vector<uint16_t>& data);
    void generateChartData(std::vector<uint16_t>& data, int average);

    void generateLiquidChartData(std::vector<uint16_t>& data, QList<QPointF>& a, QList<QPointF>& b, qreal threshold_value);
    void generateLevelChartData(std::vector<uint16_t>& data, QList<QPointF>& a, QList<QPointF>& b, qreal threshold_value);

    void processRadarDataTask();

    void configureDeviceVisualization(int ConfigType);
    //dep 

    ChartView* chartView;
    //std::unique_ptr<std::thread>
    std::thread data_generate_thread;
    std::thread data_store_thread;
    std::thread obj_store_thread;

    std::mutex mtx;
    std::queue<QList<QPointF>> point_data;
    std::queue<QList<QPointF>> threshold_data;

    std::vector<float> xData;

    bool data_ready = false;
    std::condition_variable cv;
    std::shared_ptr<std::vector<uint16_t>> fft_mag_data;
    std::shared_ptr<std::vector<uint16_t>> raw_data;
    int record_fft_mag_data_size = 0;

    const float fix = 0.045e-6;
    const float liquidSpeedRes = 3e8 / 77e9 / 2 / (46e-6 + fix) / 512;
    //const float res1 = 3e8 / 2 / (2048+6) / 1.883e6;            //理论上是2048us
    const float objectDistRes = 3e8 / 2 / (512) / 7.628e6;


    std::vector<float> calculatedSpeed;
    std::vector<float> calculatedDistance;

    ThreadSafeQueue<RangeConfiguartion> RangeQueue;
    ThreadSafeQueue<SpeedConfiguration> SpeedQueue;
    ThreadSafeQueue<RangeConfiguartion> RangeStoreQueue;
    ThreadSafeQueue<SpeedConfiguration> SpeedStoreQueue;

    float  threshold;
    int DeviceType;
    std::map<std::vector<uint16_t>, std::vector<int>> FoundPeak;

    QString basefolder;
    QString timeStampedFolder;
    QString create_time;
    QString current_time;

    std::condition_variable file_cv;
    bool file_data_ready = false;
    std::mutex file_mtx;

    std::mutex obj_mtx;
    std::condition_variable obj_cv;
    bool obj_data_ready = false;
    int framecounter = 0;
    int data_filecounter = 0;
    QString currenttime;

    QStandardItemModel* model;

    void alg_init();
    void callback_register();
    void data_store_task();
    void obj_store_task();
    void rawdata_store_param_config(int flag);

    friend bool comparetrack1d (const track1d& a, const track1d& b);
private:
    Ui::MainWindow *ui;

public slots:
    void updateChart();
    void receiveRadarData(const awr1843_sensor& data);
    void data_check_datachanged(int);


    void refreshSerialPort();
    void controlSerialPort();

};
#endif // MAINWINDOW_H
